package smcms.service.order.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.executor.result.ResultMapException;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import smcms.commons.api.entity.result.CommonsResult;
import smcms.service.order.entity.*;
import smcms.service.order.feignService.ProductService;
import smcms.service.order.mapper.OrderMapper;
import smcms.service.order.service.OrderService;
import smcms.service.order.utils.IOUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


@Service
@Transactional
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private CommonsResult commonsResult;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private ProductService productService;
    @Override
    public CommonsResult insertOrder(OrderReq req) {
        if (ObjectUtils.isEmpty(req.getProductId())) {
            return commonsResult.failed("商品ID不能为空！");
        }
        if (ObjectUtils.isEmpty(req.getProductAccount())) {
            return commonsResult.failed("订单商品数量不能为空！");
        }
        if (req.getOrderType().equals("采购订单") && "已完成".equals(req.getOrderState())) {
            RLock lock = redissonClient.getLock(req.getProductId());
            try {
                boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
                if (!res) {
                    return commonsResult.failed("系统繁忙，稍后再试！");
                }
                InventoryPlus inventoryPlus = new InventoryPlus();
                inventoryPlus.setProductId(req.getProductId());
                Integer plus = Integer.parseInt(req.getProductAccount());
                inventoryPlus.setPlus(plus);
                inventoryPlus.setType("采购订单");
                CommonsResult commonsResult = productService.productInventoryPlus(inventoryPlus);
                if (!commonsResult.getCode().equals(200)) {
                    return commonsResult.failed("更新库存失败！" + commonsResult.getData());
                }
                Date date = new Date();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                req.setCompleteTime(sdf.format(date));

            } catch (InterruptedException e) {
                return commonsResult.failed("系统繁忙，稍后再试！" + e.getMessage());
            } finally {
                lock.unlock();
            }
        }
        if ("已完成".equals(req.getOrderState()) && req.getOrderType().equals("销售订单")) {
            RLock lock = redissonClient.getLock(req.getProductId());
            try {
                boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
                if (!res) {
                    return commonsResult.failed("系统繁忙，稍后再试！");
                }
                InventoryPlus inventoryPlus = new InventoryPlus();
                inventoryPlus.setProductId(req.getProductId());
                Integer plus = Integer.parseInt(req.getProductAccount());
                plus *= -1;
                inventoryPlus.setPlus(plus);
                inventoryPlus.setType("销售订单");
                CommonsResult commonsResult = productService.productInventoryPlus(inventoryPlus);
                if (!commonsResult.getCode().equals(200)) {
                    return commonsResult.failed("更新库存失败！" + commonsResult.getMsg());
                }
                Date date = new Date();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                req.setCompleteTime(sdf.format(date));

            } catch (InterruptedException e) {
                return commonsResult.failed("系统繁忙，稍后再试！" + e.getMessage());
            } finally {
                lock.unlock();
            }
        }
        UUID uuid = UUID.randomUUID();
        req.setOrderId(uuid.toString());
        orderMapper.insertOrder(req);
        return commonsResult.success();
    }

    @Override
    public CommonsResult updateOrderInfo(OrderReq req) {
        if (ObjectUtils.isEmpty(req.getOrderId())) {
            return commonsResult.failed("订单id不能为空！");
        }
        if (ObjectUtils.isEmpty(req.getProductId())) {
            return commonsResult.failed("商品ID不能为空！");
        }
        if (ObjectUtils.isEmpty(req.getProductAccount())) {
            return commonsResult.failed("订单商品数量不能为空！");
        }
        if (req.getOrderType().equals("采购订单") && "已完成".equals(req.getOrderState())) {
            RLock lock = redissonClient.getLock(req.getProductId());
            try {
                boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
                if (!res) {
                    return commonsResult.failed("系统繁忙，稍后再试！");
                }
                InventoryPlus inventoryPlus = new InventoryPlus();
                inventoryPlus.setProductId(req.getProductId());
                Integer plus = Integer.parseInt(req.getProductAccount());
                inventoryPlus.setPlus(plus);
                inventoryPlus.setType("采购订单");
                CommonsResult commonsResult = productService.productInventoryPlus(inventoryPlus);
                if (!commonsResult.getCode().equals(200)) {
                    return commonsResult.failed("更新库存失败！" + commonsResult.getData());
                }
                Date date = new Date();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                req.setCompleteTime(sdf.format(date));

            } catch (InterruptedException e) {
                return commonsResult.failed("系统繁忙，稍后再试！" + e.getMessage());
            } finally {
                lock.unlock();
            }
        }
        if ("已完成".equals(req.getOrderState()) && req.getOrderType().equals("销售订单")) {
            RLock lock = redissonClient.getLock(req.getProductId());
            try {
                boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
                if (!res) {
                    return commonsResult.failed("系统繁忙，稍后再试！");
                }
                InventoryPlus inventoryPlus = new InventoryPlus();
                inventoryPlus.setProductId(req.getProductId());
                Integer plus = Integer.parseInt(req.getProductAccount());
                plus *= -1;
                inventoryPlus.setPlus(plus);
                inventoryPlus.setType("销售订单");
                CommonsResult commonsResult = productService.productInventoryPlus(inventoryPlus);
                if (!commonsResult.getCode().equals(200)) {
                    return commonsResult.failed("更新库存失败！" + commonsResult.getMsg());
                }
                Date date = new Date();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                req.setCompleteTime(sdf.format(date));

            } catch (InterruptedException e) {
                return commonsResult.failed("系统繁忙，稍后再试！" + e.getMessage());
            } finally {
                lock.unlock();
            }
        }
        orderMapper.updateOrderInfo(req);
        return commonsResult.success();
    }

    @Override
    public CommonsResult queryOrderList(OrderReq req) {

        int pageSize = req.getPageSize() == 0 ? 10 : req.getPageSize();
        int pageNum = req.getPageNum() == 0 ? 1 : req.getPageNum();
        Page<OrderResp> page = PageHelper.startPage(pageNum, pageSize);

        List<OrderResp> orderResps = orderMapper.queryOrderList(req);
        PageInfo<OrderResp> pageInfo = page.toPageInfo();
        pageInfo.setList(orderResps);
        return commonsResult.success(pageInfo);
    }

    @Override
    public CommonsResult deleteOrderByIds(String req) {
        if (req.isEmpty()) {
            return commonsResult.failed("id为空！");
        }
        String[] ids = req.split(",");
        orderMapper.deleteOrderByIds(Arrays.asList(ids));
        return commonsResult.success();
    }

    @Override
    public CommonsResult exportOrderList(OrderExportReq req, HttpServletResponse response) {
        if (StringUtils.isEmpty(req.getIds())) {
            throw new IllegalArgumentException("导出订单id不能为空！");
        }
        String[] ids = req.getIds().split(",");
        List<OrderResp> orderResps = orderMapper.queryOrderByIds(req.getCloudId(), Arrays.asList(ids));
        List<OrderListExport> orderList = orderResps.stream().map(entity -> {
            OrderListExport orderListExport = new OrderListExport();
            BeanUtils.copyProperties(entity, orderListExport);
            return orderListExport;
        }).collect(Collectors.toList());
        String[] headName = new String[] {
                "订单编号", "商品名称", "创建时间", "商品类型", "商品价格", "商店名称"
                , "订单状态", "商品数量", "订单类型", "订单完成时间"
        };
        IOUtils.exportExcel(orderList, "订单导出列表", response, OrderListExport.class, Arrays.asList(headName));
        return commonsResult.success("导出数据成功！");
    }

    @Override
    public void importTemplate(OrderReq req, HttpServletResponse response) {
        if (ObjectUtils.isEmpty(req.getCloudId())) {
            throw new IllegalArgumentException("云id不能为空！");
        }
        ProductReq productReq = new ProductReq();
        productReq.setCloudId(req.getCloudId());
        if (!ObjectUtils.isEmpty(req.getCloudStoreId())) {
            productReq.setCloudStoreId(req.getCloudStoreId());
        }
        List<ProductTemp> productTemps = productService.queryProductExport(productReq);
        String[] head = new String[]{"商店id", "商品id",
                "商品名称", "商品类型", "商品价格",
                "商店名称", "商品数量", "订单类型(采购/销售订单)"};
        IOUtils.exportExcel(productTemps, "订单导入模板", response, ProductTemp.class, Arrays.asList(head));
    }

    @Override
    public CommonsResult importOrderList(MultipartFile file, HttpServletRequest request, HttpServletResponse response) {
        if (file.isEmpty()) {
            return commonsResult.failed("文件不能为空！");
        }
        try {
            List<Object> objects = IOUtils.importExcel(file, ImportOrderReq.class);
            List<OrderReq> orderReqList = objects.stream().map(entity -> {
                OrderReq orderReq = new OrderReq();
                UUID uuid = UUID.randomUUID();
                orderReq.setOrderId(uuid.toString());
                BeanUtils.copyProperties(entity, orderReq);
                orderReq.setOrderState("未完成");
                orderReq.setCloudId(request.getHeader("cloudId"));
                return orderReq;
            })
                    .collect(Collectors.toList());
            orderMapper.addOrderByBatch(orderReqList);
        } catch (IOException e) {
            return commonsResult.failed("IO异常！");
        }catch (Exception e) {
            return commonsResult.failed(e.getMessage());
        }
        return commonsResult.success();
    }
}
